const StockService = require('../../utils/stockService')
const TechnicalAnalysis = require('../../utils/technicalAnalysis')
const uCharts = require('../../utils/u-charts.min')

let kChart = null;

Page({
  data: {
    capital: '',
    selectedStock: null,
    stockList: [],
    searchKeyword: '',
    searchHistory: [],
    showHistory: false,
    recommendation: null,
    technicalData: {
      ma20: null,
      ma60: null,
      rsi: null,
      macd: null
    },
    realTimeData: null,
    klineData: null,
    riskAssessment: null,
    opts: null,
    chartData: {
      categories: [],
      series: []
    }
  },

  onLoad() {
    console.log('页面加载完成');
    const history = wx.getStorageSync('searchHistory') || [];
    const hasSearched = wx.getStorageSync('hasSearched') || false;
    this.setData({ 
      searchHistory: history,
      showHistory: hasSearched
    });
  },

  onReady() {
    console.log('页面准备完成');
  },

  onUnload() {
    // 页面卸载时清理图表实例
    if (kChart) {
      kChart.destroy();
      kChart = null;
    }
  },

  // 更新K线图数据
  updateKLineChart() {
    console.log('开始更新K线图');
    const { klineData } = this.data;
    if (!klineData || !Array.isArray(klineData) || klineData.length === 0) {
      console.warn('无有效K线数据，无法绘制图表');
      return;
    }

    try {
      // 处理数据
      const categories = klineData.map(item => item.date.substring(5));
      const series = [{
        name: 'K线',
        data: klineData.map(item => ({
          time: item.date,
          open: parseFloat(item.open),
          close: parseFloat(item.close),
          high: parseFloat(item.high),
          low: parseFloat(item.low),
          volume: parseFloat(item.volume || 0)
        }))
      }];

      console.log('处理后的K线数据：', { categories, series });

      // 重新初始化图表
      this.initKLineChart(categories, series[0].data);

    } catch (error) {
      console.error('更新K线图失败：', error);
      wx.showToast({
        title: '图表更新失败',
        icon: 'none'
      });
    }
  },

  initKLineChart(categories, data) {
    const query = wx.createSelectorQuery();
    query.select('#k-line-chart')
      .fields({ node: true, size: true })
      .exec((res) => {
        if (!res[0]) {
          console.error('获取canvas节点失败');
          return;
        }

        const canvas = res[0].node;
        const ctx = canvas.getContext('2d');
        
        const canvasWidth = res[0].width;
        const canvasHeight = res[0].height;
        
        canvas.width = canvasWidth * 2;
        canvas.height = canvasHeight * 2;
        
        const opts = {
          type: 'candle',
          context: ctx,
          canvas: canvas,
          width: canvasWidth * 2,
          height: canvasHeight * 2,
          categories: categories,
          series: [{
            name: 'K线',
            data: data
          }],
          padding: [15, 60, 0, 15],
          xAxis: {
            disableGrid: true,
            itemCount: 5,
            labelCount: 5,
            scrollShow: true,
            scrollAlign: 'right'
          },
          yAxis: {
            gridType: 'dash',
            splitNumber: 5,
            format: (val) => val.toFixed(2),
            position: 'right',
            axisLine: true,
            labelCount: 5,
            title: '价格',
            titleFontSize: 12,
            titleFontColor: '#666666'
          },
          extra: {
            candle: {
              color: {
                upLine: '#f04864',
                upFill: '#f04864',
                downLine: '#2fc25b',
                downFill: '#2fc25b'
              }
            }
          },
          enableScroll: true,
          enableMarkLine: true,
          dataLabel: true,
          dataPointShape: true,
          legend: {
            show: true,
            position: 'top',
            float: 'right',
            padding: 10,
            margin: 0
          },
          tooltip: {
            showBox: true,
            showArrow: true,
            showCategory: true,
            borderWidth: 0,
            borderRadius: 0,
            borderColor: '#000000',
            borderOpacity: 0.7,
            bgColor: '#000000',
            bgOpacity: 0.7,
            gridType: 'dash',
            dashLength: 4,
            gridColor: '#1890ff',
            fontColor: '#FFFFFF',
            splitLine: true,
            horizentalLine: true,
            xAxisLabel: true,
            yAxisLabel: true,
            labelBgColor: '#000000',
            labelBgOpacity: 0.7,
            labelFontColor: '#FFFFFF'
          }
        };

        if (kChart) {
          // 如果图表已存在，先销毁它
          kChart.destroy();
        }
        
        // 创建新的图表实例
        kChart = new uCharts(opts);
      });
  },

  // 搜索框获得焦点时
  onSearchFocus() {
    // 清空已选股票，显示搜索列表
    this.setData({
      selectedStock: null,
      searchKeyword: '',
      stockList: [],
      realTimeData: null,
      technicalData: {
        ma20: null,
        ma60: null,
        rsi: null,
        macd: null
      },
      klineData: null,
      riskAssessment: null
    })
  },

  // 搜索股票
  onSearchInput(e) {
    const keyword = e.detail.value.trim()
    console.log('搜索关键词：', keyword)
    
    this.setData({ 
      searchKeyword: keyword,
      selectedStock: null  // 清除已选择的股票
    })
    
    if (keyword.length >= 2) {
      // 设置已搜索标志
      wx.setStorageSync('hasSearched', true)
      this.setData({ showHistory: true })

      // 添加到搜索历史
      this.addToSearchHistory(keyword)

      wx.showLoading({
        title: '搜索中...',
        mask: true
      })
      
      StockService.searchStocks(keyword)
        .then(result => {
          console.log('搜索结果：', result)
          console.log('搜索结果类型：', typeof result)
          console.log('搜索结果stocks属性：', result?.stocks)
          
          wx.hideLoading()
          
          // 确保返回的数据中包含stocks数组
          if (result && Array.isArray(result.stocks)) {
            console.log('设置股票列表：', result.stocks)
            // 只有当当前搜索关键词仍然有效时才更新列表
            if (this.data.searchKeyword === keyword) {
              this.setData({
                stockList: result.stocks
              }, () => {
                console.log('更新后的股票列表：', this.data.stockList)
              })
            }
          } else {
            console.log('搜索结果无效，清空股票列表')
            this.setData({
              stockList: []
            })
          }
        })
        .catch(error => {
          console.error('搜索股票失败：', error)
          console.error('错误详情：', error.message)
          console.error('错误堆栈：', error.stack)
          wx.hideLoading()
          this.setData({
            stockList: []
          })
          wx.showToast({
            title: '搜索失败',
            icon: 'none'
          })
        })
    } else {
      console.log('关键词长度不足，清空股票列表')
      this.setData({
        stockList: []
      })
    }
  },

  // 选择股票
  onStockSelect(e) {
    const index = e.currentTarget.dataset.index
    const selectedStock = this.data.stockList[index]
    console.log('选择股票：', selectedStock)
    
    this.setData({
      selectedStock,
      stockList: [], // 清空搜索列表
      searchKeyword: `${selectedStock.name}(${selectedStock.code})` // 更新搜索框显示
    })

    // 获取实时数据
    this.fetchRealTimeData(selectedStock.code)
    // 获取K线数据
    this.fetchKLineData(selectedStock.code)
  },

  // 添加到搜索历史
  addToSearchHistory(keyword) {
    const history = this.data.searchHistory
    // 移除已存在的相同关键词
    const filteredHistory = history.filter(item => item !== keyword)
    // 添加到历史记录开头
    filteredHistory.unshift(keyword)
    // 只保留最近10条记录
    const newHistory = filteredHistory.slice(0, 10)
    
    this.setData({ searchHistory: newHistory })
    // 保存到本地存储
    wx.setStorageSync('searchHistory', newHistory)
  },

  // 从搜索历史中选择关键词
  onHistorySelect(e) {
    const index = e.currentTarget.dataset.index
    const keyword = this.data.searchHistory[index]
    
    this.setData({
      searchKeyword: keyword
    })

    // 触发搜索
    this.onSearchInput({
      detail: { value: keyword }
    })
  },

  // 清空搜索历史
  clearSearchHistory() {
    this.setData({ 
      searchHistory: [],
      showHistory: false 
    })
    wx.setStorageSync('searchHistory', [])
    wx.setStorageSync('hasSearched', false)
  },

  // 清除已选择的股票
  clearSelectedStock() {
    this.setData({
      selectedStock: null,
      searchKeyword: '',
      realTimeData: null,
      technicalData: {
        ma20: null,
        ma60: null,
        rsi: null,
        macd: null
      },
      klineData: null,
      riskAssessment: null,
      recommendation: null
    })
  },

  // 获取实时数据
  async fetchRealTimeData(code) {
    try {
      const data = await StockService.getStockData(code)
      if (data) {
        this.setData({ realTimeData: data })
        // 更新技术指标
        this.updateTechnicalData()
      }
    } catch (error) {
      console.error('获取实时数据失败：', error)
      wx.showToast({
        title: '获取数据失败',
        icon: 'none'
      })
    }
  },

  // 获取K线数据
  async fetchKLineData(code) {
    try {
      wx.showLoading({
        title: '加载数据...',
        mask: true
      });
      
      console.log('开始获取K线数据，股票代码：', code);
      const klineData = await StockService.getKLineData(code);
      console.log('获取到原始K线数据：', klineData);
      
      if (!klineData || !Array.isArray(klineData) || klineData.length === 0) {
        console.error('K线数据无效');
        wx.showToast({
          title: '数据获取失败',
          icon: 'none'
        });
        return;
      }
      
      // 检查数据格式
      const sampleData = klineData[0];
      const requiredFields = ['date', 'open', 'close', 'high', 'low'];
      const missingFields = requiredFields.filter(field => !sampleData.hasOwnProperty(field));
      
      if (missingFields.length > 0) {
        console.error('K线数据缺少必要字段：', missingFields);
        wx.showToast({
          title: '数据格式不完整',
          icon: 'none'
        });
        return;
      }

      // 设置数据并等待更新完成
      await new Promise(resolve => {
        this.setData({ klineData }, resolve);
      });

      console.log('K线数据已更新，开始更新技术指标');
      this.updateTechnicalData();
      
      // 延迟更新图表，确保组件已完全初始化
      setTimeout(() => {
        console.log('开始更新K线图');
        this.updateKLineChart();
      }, 500);

    } catch (error) {
      console.error('获取K线数据失败：', error);
      wx.showToast({
        title: '获取数据失败',
        icon: 'none'
      });
    } finally {
      wx.hideLoading();
    }
  },

  // 更新技术指标
  updateTechnicalData() {
    const { klineData } = this.data;
    if (!klineData || !Array.isArray(klineData) || klineData.length === 0) {
      console.warn('无有效K线数据，无法计算技术指标');
      return;
    }

    console.log('开始计算技术指标');
    
    // 计算MA数组
    const ma20Array = TechnicalAnalysis.calculateMA(20, klineData);
    const ma60Array = TechnicalAnalysis.calculateMA(60, klineData);
    
    // 获取最新的MA值
    const ma20 = ma20Array ? ma20Array[ma20Array.length - 1] : null;
    const ma60 = ma60Array ? ma60Array[ma60Array.length - 1] : null;
    
    const technicalData = {
      ma20: ma20 ? ma20.toFixed(2) : null,
      ma60: ma60 ? ma60.toFixed(2) : null,
      rsi: TechnicalAnalysis.calculateRSI(klineData).toFixed(2),
      macd: TechnicalAnalysis.calculateMACD(klineData).toFixed(2)
    };
    console.log('计算得到的技术指标：', technicalData);

    // 格式化技术指标显示，使用更紧凑的格式
    const technicalInfo = [
      `MA20:${technicalData.ma20 || '-'}`,
      `MA60:${technicalData.ma60 || '-'}`,
      `RSI:${technicalData.rsi || '-'}`,
      `MACD:${technicalData.macd || '-'}`
    ].join('  ');  // 使用两个空格分隔，而不是 " | "

    this.setData({ 
      technicalData,
      technicalInfo
    }, () => {
      // 更新风险评估
      this.updateRiskAssessment();
    });
  },

  // 更新风险评估
  updateRiskAssessment() {
    const { klineData, technicalData } = this.data;
    
    // 检查必要的数据是否存在
    if (!klineData || !Array.isArray(klineData) || klineData.length === 0) {
      console.warn('无有效K线数据，无法进行风险评估');
      return;
    }

    if (!technicalData) {
      console.warn('无有效技术指标数据，无法进行风险评估');
      return;
    }

    try {
      const riskAssessment = TechnicalAnalysis.assessRisk(klineData, technicalData);
      
      // 添加样式类
      riskAssessment.levelClass = this.getRiskLevelClass(riskAssessment.score);
      
      this.setData({ riskAssessment });
    } catch (error) {
      console.error('风险评估失败：', error);
      wx.showToast({
        title: '风险评估失败',
        icon: 'none'
      });
    }
  },

  getRiskLevelClass(score) {
    if (score >= 80) return 'extreme-high'
    if (score >= 60) return 'high'
    if (score >= 40) return 'medium'
    return 'low'
  },

  generateRecommendation() {
    const { klineData, technicalData, riskAssessment, capital, realTimeData } = this.data;
    
    // 检查必要的数据是否存在
    if (!klineData || !Array.isArray(klineData) || klineData.length === 0) {
      wx.showToast({
        title: '暂无K线数据',
        icon: 'none'
      });
      return;
    }

    if (!technicalData) {
      wx.showToast({
        title: '暂无技术指标数据',
        icon: 'none'
      });
      return;
    }

    if (!riskAssessment) {
      wx.showToast({
        title: '暂无风险评估数据',
        icon: 'none'
      });
      return;
    }

    if (!realTimeData) {
      wx.showToast({
        title: '暂无实时数据',
        icon: 'none'
      });
      return;
    }

    if (!capital || parseFloat(capital) <= 0) {
      wx.showToast({
        title: '请输入有效的投资金额',
        icon: 'none'
      });
      return;
    }

    const capitalAmount = parseFloat(capital);
    const currentPrice = parseFloat(realTimeData.price);
    const minRequiredCapital = currentPrice * 100;
    
    // 计算波动率
    const volatility = this.calculateVolatility(klineData);
    
    // 计算建议仓位比例
    let positionRatio = 0;
    if (riskAssessment.score < 40) {
      positionRatio = 0.6;
    } else if (riskAssessment.score < 60) {
      positionRatio = 0.4;
    } else if (riskAssessment.score < 80) {
      positionRatio = 0.2;
    } else {
      positionRatio = 0;
    }

    // 计算建议买入股数（向下取整到100的倍数）
    const maxShares = Math.floor((capitalAmount * positionRatio) / currentPrice / 100) * 100;
    
    // 计算实际投入资金
    const actualInvestment = maxShares * currentPrice;
    
    // 计算止损价格（根据波动率动态调整）
    const stopLossRatio = Math.min(Math.max(volatility * 2, 0.03), 0.08);
    const stopLossPrice = (currentPrice * (1 - stopLossRatio)).toFixed(2);
    
    // 计算止盈目标（根据风险评估和波动率动态调整）
    const profitRatio = stopLossRatio * (riskAssessment.score >= 60 ? 3 : 2);
    const targetPrice = (currentPrice * (1 + profitRatio)).toFixed(2);
    
    // 综合技术分析和风险评估生成建议
    const trend = TechnicalAnalysis.analyzeTrend(klineData);
    
    let recommendation = {
      content: 
        `投资金额：${capitalAmount.toFixed(2)}元\n` +
        `当前股价：${currentPrice}元\n` +
        `市场趋势：${trend.trend}（${trend.details.priceChange}）\n` +
        `MA5趋势：${trend.details.ma5Trend}\n` +
        `MA10趋势：${trend.details.ma10Trend}\n` +
        `波动率：${(volatility * 100).toFixed(1)}%\n` +
        `风险等级：${riskAssessment.level}\n\n` +
        '风险提示：\n' +
        '投资有风险，建议仅使用闲置资金进行投资，确保投资金额在可承受范围内。',
      strategy: ''
    };

    if (riskAssessment.score >= 80) {
      recommendation.strategy = 
        '当前风险极高，不建议开仓。\n\n' +
        '建议操作：\n' +
        `1. 暂时观望，等待风险降低\n` +
        `2. 考虑将 ${capitalAmount.toFixed(2)} 元投资于更稳健的标的\n` +
        `3. 可以考虑分散投资到多个低风险标的`;
    } else if (trend.strength >= 0.3) {
      if (capitalAmount >= minRequiredCapital) {
        // 计算可能的总股数（必须是100的倍数）
        const totalPossibleShares = Math.floor(capitalAmount / currentPrice / 100) * 100;
        
        // 如果可能的总股数为0，说明资金不足
        if (totalPossibleShares === 0) {
          recommendation.strategy = 
            `当前投资金额不足提示：\n\n` +
            `1. 当前投资金额 ${capitalAmount.toFixed(2)} 元不足以购买100股\n` +
            `2. 购买100股需要至少 ${minRequiredCapital.toFixed(2)} 元\n\n` +
            '建议操作：\n' +
            '1. 增加投资金额\n' +
            '2. 选择价格较低的其他标的\n' +
            '3. 考虑购买ETF等其他投资品种';
          return;
        }
        
        // 根据风险等级计算建议股数
        const recommendedShares = Math.max(Math.floor(totalPossibleShares * positionRatio / 100) * 100, 100);
        // 第一批建议买入股数（至少100股）
        const firstBatchShares = Math.max(Math.floor(recommendedShares / 2 / 100) * 100, 100);
        
        const firstBatchAmount = (firstBatchShares * currentPrice).toFixed(2);
        const totalRecommendedAmount = (recommendedShares * currentPrice).toFixed(2);
        const remainingAmount = (capitalAmount - parseFloat(firstBatchAmount)).toFixed(2);
        
        recommendation.strategy = 
          '建议买入策略：\n\n' +
          `1. 第一批买入 ${firstBatchShares} 股，需资金 ${firstBatchAmount} 元\n` +
          `2. 保留 ${remainingAmount} 元等待回调后买入\n` +
          `3. 总建议仓位 ${recommendedShares} 股，约占总资金 ${(positionRatio * 100).toFixed(0)}%\n\n` +
          '风控建议：\n' +
          `1. 设置止损价：${stopLossPrice} 元（-${(stopLossRatio * 100).toFixed(1)}%）\n` +
          `2. 设置止盈目标：${targetPrice} 元（+${(profitRatio * 100).toFixed(1)}%）\n` +
          `3. 单笔交易不超过 ${(parseFloat(totalRecommendedAmount) * 0.5).toFixed(2)} 元`;
      } else {
        recommendation.strategy = 
          `当前投资金额不足提示：\n\n` +
          `1. 当前投资金额 ${capitalAmount.toFixed(2)} 元不足以购买100股\n` +
          `2. 购买100股需要至少 ${minRequiredCapital.toFixed(2)} 元\n\n` +
          '建议操作：\n' +
          '1. 增加投资金额\n' +
          '2. 选择价格较低的其他标的\n' +
          '3. 考虑购买ETF等其他投资品种';
      }
    } else if (trend.strength <= -0.3) {
      // 计算可能的总股数（必须是100的倍数）
      const suggestedPrice = (currentPrice * 0.9).toFixed(2);
      const possibleShares = Math.max(Math.floor((capitalAmount * 0.3) / suggestedPrice / 100) * 100, 100);
      
      recommendation.strategy = 
        '当前处于下跌趋势，建议操作：\n\n' +
        '1. 暂时持币观望\n' +
        `2. 等待股价回调至 ${suggestedPrice} 元附近\n` +
        `3. 届时可考虑买入 ${possibleShares} 股，约需资金 ${(possibleShares * suggestedPrice).toFixed(2)} 元\n\n` +
        '建议等待以下信号之一出现：\n' +
        '1. MACD金叉\n' +
        '2. RSI超卖\n' +
        '3. 放量上涨突破';
    } else {
      // 计算试探性建仓的股数（必须是100的倍数，且至少100股）
      const testAmount = (capitalAmount * 0.2).toFixed(2);
      const testShares = Math.max(Math.floor(parseFloat(testAmount) / currentPrice / 100) * 100, 100);
      
      // 如果资金不足以购买100股，给出相应提示
      if (capitalAmount < minRequiredCapital) {
        recommendation.strategy = 
          `当前投资金额不足提示：\n\n` +
          `1. 当前投资金额 ${capitalAmount.toFixed(2)} 元不足以购买100股\n` +
          `2. 购买100股需要至少 ${minRequiredCapital.toFixed(2)} 元\n\n` +
          '建议操作：\n' +
          '1. 增加投资金额\n' +
          '2. 选择价格较低的其他标的\n' +
          '3. 考虑购买ETF等其他投资品种';
      } else {
        recommendation.strategy = 
          '市场处于盘整阶段，建议操作：\n\n' +
          `1. 使用 ${testAmount} 元（总资金的20%）试探性建仓\n` +
          `2. 可买入 ${testShares} 股作为试探仓位\n` +
          `3. 设置止损价位：${stopLossPrice} 元\n` +
          `4. 剩余资金 ${(capitalAmount * 0.8).toFixed(2)} 元等待明确信号`;
      }
    }

    this.setData({ recommendation });
  },

  // 计算波动率
  calculateVolatility(data) {
    if (!data || data.length < 2) return 0
    
    const returns = []
    for (let i = 1; i < data.length; i++) {
      const prev = parseFloat(data[i - 1].close)
      const curr = parseFloat(data[i].close)
      returns.push((curr - prev) / prev)
    }
    
    const mean = returns.reduce((a, b) => a + b, 0) / returns.length
    const variance = returns.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / returns.length
    return Math.sqrt(variance)
  },

  // 添加资金输入处理方法
  onCapitalInput(e) {
    const value = e.detail.value;
    this.setData({
      capital: value
    });
  }
}) 